/*
 * @Author: SamZhang samzhang@apjcorp.com
 * @Date: 2022-12-02 10:14:44
 * @LastEditors: SamZhang samzhang@apjcorp.com
 * @LastEditTime: 2023-02-16 15:08:35
 * @FilePath: /circulation-web/src/components/Collections.tsx
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
import * as React from "react";
import {
  GenericEditableConfigList,
  EditableConfigListStateProps,
  EditableConfigListDispatchProps,
  EditableConfigListOwnProps,
} from "./EditableConfigList";
import { connect } from "react-redux";
import * as PropTypes from "prop-types";
import ActionCreator from "../actions";
import {
  CollectionsData,
  CollectionData,
  LibraryData,
  LibraryRegistrationsData,
  ServiceData,
} from "../interfaces";
import ServiceWithRegistrationsEditForm from "./ServiceWithRegistrationsEditForm";
import TrashIcon from "./icons/TrashIcon";

export interface CollectionsStateProps
  extends EditableConfigListStateProps<CollectionsData> {
  isFetchingLibraryRegistrations?: boolean;
}

export interface CollectionsDispatchProps
  extends EditableConfigListDispatchProps<CollectionsData> {
  registerLibrary: (data: FormData) => Promise<void>;
  fetchLibraryRegistrations?: () => Promise<LibraryRegistrationsData>;
}

export interface CollectionsProps
  extends CollectionsStateProps,
    CollectionsDispatchProps,
    EditableConfigListOwnProps {}

class CollectionEditForm extends ServiceWithRegistrationsEditForm<
  CollectionsData
> {}

/**
 * Right panel for collections on the system configuration page.
 * Shows a list of current collections and allows creating a new
 * collection or editing or deleting an existing collection.
 * Also allows registering libraries with the collection when
 * the collection supports it.
 * ```
 * <Collections />
 * ```
 */
let collectionShowStatus = null;
const applocation_root = localStorage.getItem("MOBEBR_CONFIG_APPLICATION_ROOT");

export class Collections extends GenericEditableConfigList<
  CollectionsData,
  CollectionData,
  CollectionsProps
> {
  EditForm = CollectionEditForm;
  listDataKey = "collections";
  itemTypeName = "collection";
  urlBase = applocation_root + "/admin/web/config/collections/";
  identifierKey = "id";
  labelKey = "name";
  links = this.renderLinks();
  // collectionShowStatus = {};

  constructor(props) {
    super(props);
    if (collectionShowStatus === null) this.getCollectionShowStatus();
  }

  // 获取collection的显示/隐藏状态
  // "/admin/collections"

  static childContextTypes: React.ValidationMap<any> = {
    registerLibrary: PropTypes.func,
  };

  getChildContext() {
    return {
      registerLibrary: (library: LibraryData) => {
        if (this.itemToEdit()) {
          const data = new (window as any).FormData();
          data.append("library_short_name", library.short_name);
          data.append("collection_id", this.itemToEdit().id);
          this.props.registerLibrary(data).then(() => {
            if (this.props.fetchLibraryRegistrations) {
              this.props.fetchLibraryRegistrations();
            }
          });
        }
      },
    };
  }

  UNSAFE_componentWillMount() {
    super.UNSAFE_componentWillMount();
    if (this.props.fetchLibraryRegistrations) {
      this.props.fetchLibraryRegistrations();
    }
  }

  renderLinks(): { [key: string]: JSX.Element } {
    const linkBase =
      applocation_root + "/admin/web/troubleshooting/self-tests/collections";
    const linkElement = <a href={linkBase}>the troubleshooting page</a>;
    return {
      info: (
        <>Self-tests for the collections have been moved to {linkElement}</>
      ),
      footer: <>Problems with your collections? Please visit {linkElement}.</>,
    };
  }

  renderLi(item, index): JSX.Element {
    if (item.marked_for_deletion) {
      return (
        <li className="deleted-collection" key={index}>
          <TrashIcon />
          <h4>{this.label(item)}</h4>
          <p>
            This collection cannot be edited and is currently being deleted. The
            deletion process is gradual and this collection will be removed once
            it is complete.
          </p>
        </li>
      );
    }

    // 处理showOrHideCollection变量提升问题,故移至此处
    function showOrHideCollection(item, nowShowStatus) {
      // nowShowStatus:
      //  1:表示未隐藏，默认
      //  2：表示正在操作中
      //  3：表示已隐藏
      return function () {
        if (nowShowStatus !== 1 && nowShowStatus !== 3) {
          location.reload();
          return;
        }
        const actionLabel = nowShowStatus === 1 ? "Hide" : "Show";
        if (
          window.confirm(
            "Are you sure to " +
              actionLabel +
              ` "` +
              item.name +
              `" in Catalogue?`
          )
        ) {
          const suppressedLable =
            nowShowStatus === 1 ? "suppressed" : "unsuppressed";

          let url = "/admin/collection/" + item.id + "/" + suppressedLable;
          const applocation_root = localStorage.getItem(
            "MOBEBR_CONFIG_APPLICATION_ROOT"
          );
          url = applocation_root + url;

          fetch(url, { method: "post" }).then((response) => {
            if (response.ok) location.reload();
            else alert("Error, please try again");
          });
        }
      };
    }

    // return (<p>测试</p>);
    // return super.renderLi(item, index);
    // console.log('collectionShowStatus:',collectionShowStatus)
    if (collectionShowStatus && collectionShowStatus["" + item.id] !== null) {
      const showStatus = collectionShowStatus["" + item.id];
      return super.renderLi_ebrCollection(
        item,
        index,
        showStatus,
        showOrHideCollection(item, showStatus)
      );
    } else {
      return super.renderLi(item, index);
    }
  }

  async delete(item: CollectionData): Promise<void> {
    const deleteInfo =
      "This action cannot be undone. Deletion will not happen " +
      "immediately but gradually. Until the collection is completely deleted, " +
      "it will remain in the list and will be uneditable.";
    if (
      window.confirm(`Set "${this.label(item)}" for deletion? ${deleteInfo}`)
    ) {
      await this.props.deleteItem(item[this.identifierKey]);
      this.props.fetchData();
    }
  }

  getCollectionShowStatus() {
    let url = "/admin/collections";
    const applocation_root = localStorage.getItem(
      "MOBEBR_CONFIG_APPLICATION_ROOT"
    );
    url = applocation_root + url;

    fetch(url, { method: "get" })
      .then((response) => {
        if (response && response.ok) return response.json();
      })
      .then((data) => {
        if (!data) return;
        const collections = data["collections"];
        const map = {};
        for (let i = 0; i < collections.length; i++) {
          const collection = collections[i];
          const showStatus = parseInt(collection["marked_for_hide"]);
          map["" + collection["id"]] = showStatus;
        }
        // console.log('collection状态',map)
        collectionShowStatus = map;
      });
  }

  // async test(item: CollectionData): Promise<void> {
  //   // if (window.confirm(`S "` + this.label(item) + `"?`)) {
  //   //   // await this.props.deleteItem(item[this.identifierKey]);
  //   //   // this.props.fetchData();
  //   // }
  //   // this.props.fetchData();
  // }
}

function mapStateToProps(state, ownProps) {
  const data = Object.assign(
    {},
    (state.editor.collections && state.editor.collections.data) || {}
  );
  if (state.editor.libraries && state.editor.libraries.data) {
    data.allLibraries = state.editor.libraries.data.libraries;
  }
  if (
    state.editor.collectionLibraryRegistrations &&
    state.editor.collectionLibraryRegistrations.data
  ) {
    data.libraryRegistrations =
      state.editor.collectionLibraryRegistrations.data.library_registrations;
  }
  // fetchError = an error involving loading the list of collections; formError = an error upon
  // submission of the create/edit form (including upon submitting a change to a library's registration).
  return {
    data: data,
    responseBody:
      state.editor.collections && state.editor.collections.successMessage,
    fetchError: state.editor.collections.fetchError,
    formError:
      state.editor.collections.formError ||
      (state.editor.collectionLibraryRegistrations &&
        state.editor.collectionLibraryRegistrations.fetchError) ||
      (state.editor.registerLibraryWithCollection &&
        state.editor.registerLibraryWithCollection.fetchError),
    isFetching:
      state.editor.collections.isFetching || state.editor.collections.isEditing,
    isFetchingLibraryRegistrations:
      state.editor.collectionLibraryRegistrations &&
      state.editor.collectionLibraryRegistrations.isFetching,
  };
}

function mapDispatchToProps(dispatch, ownProps) {
  const actions = new ActionCreator(null, ownProps.csrfToken);
  return {
    fetchData: () => dispatch(actions.fetchCollections()),
    editItem: (data: FormData) => dispatch(actions.editCollection(data)),
    deleteItem: (identifier: string | number) =>
      dispatch(actions.deleteCollection(identifier)),
    registerLibrary: (data: FormData) =>
      dispatch(actions.registerLibraryWithCollection(data)),
    fetchLibraryRegistrations: () =>
      dispatch(actions.fetchCollectionLibraryRegistrations()),
  };
}

const ConnectedCollections = connect<
  EditableConfigListStateProps<CollectionsData>,
  EditableConfigListDispatchProps<CollectionsData>,
  EditableConfigListOwnProps
>(
  mapStateToProps,
  mapDispatchToProps
)(Collections);

export default ConnectedCollections;
